package cn.seecoder.courselearning.serviceimpl.course;

import cn.seecoder.courselearning.mapperservice.course.CourseLikesMapper;
import cn.seecoder.courselearning.mapperservice.course.CourseMapper;
import cn.seecoder.courselearning.po.course.Course;
import cn.seecoder.courselearning.po.order.CourseOrder;
import cn.seecoder.courselearning.service.course.CourseService;
import cn.seecoder.courselearning.service.order.QueryOrderService;
import cn.seecoder.courselearning.util.Constant;
import cn.seecoder.courselearning.util.PageInfoUtil;
import cn.seecoder.courselearning.vo.course.CourseVO;
import cn.seecoder.courselearning.vo.ResultVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CourseServiceImpl implements CourseService {
    @Resource
    private CourseMapper courseMapper;
    @Resource
    private CourseLikesMapper courseLikesMapper;

    private QueryOrderService orderService;

    @Autowired
    public void setOrderService(QueryOrderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public PageInfo<CourseVO> getCourses(Integer currPage, Integer pageSize, Integer uid, String key) {
        if(currPage==null || currPage<1) currPage=1;
        PageHelper.startPage(currPage, pageSize);
        PageInfo<Course> po = new PageInfo<>(courseMapper.queryAll(key));
        return getCourseVOPageInfo(uid, po);
    }

    @Override
    public PageInfo<CourseVO> getCoursesByType(Integer currPage, Integer pageSize, Integer uid, String type) {
        if(currPage==null || currPage<1) currPage=1;
        PageHelper.startPage(currPage, pageSize);
        PageInfo<Course> po = new PageInfo<>(courseMapper.selectByType(type));
        return getCourseVOPageInfo(uid, po);
    }

    @Override
    public PageInfo<CourseVO> getHotCourses(Integer currPage, Integer pageSize, Integer uid) {
        if(currPage==null || currPage<1) currPage=1;
        PageHelper.startPage(currPage, pageSize);
        PageInfo<Course> po = new PageInfo<>(courseMapper.selectHotCourses());
        return getCourseVOPageInfo(uid, po);
    }

    // todo 修改getBoughtCourses的实现
    @Override
    public List<CourseVO> getBoughtCourses(Integer uid) {
        /*
        List<CourseVO> ret = new ArrayList<>();
        List<Course> courseList = courseMapper.selectByStudentId(uid);
        for(Course course: courseList){
            ret.add(new CourseVO(course, true, false));
        }
        return ret;
            ↑原框架代码
         */

        List<CourseVO> ret = new ArrayList<>();
        List<Course> courseList = courseMapper.selectByStudentId(uid);
        for(Course course: courseList){
            //在po/Course.java中新增了一个构造函数                                       ↓比原来多了一个参数
            //CourseVO(@NonNull Course course, boolean bought, boolean manageable, boolean isliked)
            //原因： 修改前，假设学生用户A、B都购买了课程C1，那么，在B没有为C1点赞的情况下，A为C1点赞后，
            //      登录B的账户会发现已购课程一栏中会出现灰色的图标（BUG）、点赞数为1。
            //      修改后，登录B的账户会发现已购课程一栏中会出现粉色的图标（正确）、点赞数为1。
            ret.add(new CourseVO(course, true, false, getliked(uid, course.getId())));
        }
        return ret;
    }

    @Override
    public List<CourseVO> getManageableCourses(Integer uid) {
        List<CourseVO> ret = new ArrayList<>();
        List<Course> courseList = courseMapper.selectByTeacherId(uid);
        for(Course course: courseList){
            ret.add(new CourseVO(course, false, true,getliked(uid, course.getId())));
        }
        return ret;
    }

    @Override
    public CourseVO getCourse(Integer courseId, Integer uid) {
        Course course = courseMapper.selectByPrimaryKey(courseId);
        boolean bought = false;
        boolean manageable = false;
        if(uid != null && uid > 0) {
            CourseOrder order = orderService.queryMostRecentOrder(uid, courseId);
            if(order != null)
                bought = order.getStatus().equals(Constant.ORDER_STATUS_SUCCESS);
            manageable = uid.equals(course.getTeacherId());
        }
        return new CourseVO(course, bought, manageable,getliked(uid, course.getId()));
    }

    @Override
    public ResultVO<CourseVO> createCourse(CourseVO courseVO) {
        courseVO.setCreateTime(new Date());

        for(Course course: courseMapper.selectByTeacherId(courseVO.getTeacherId())){
            if (course.getName().equals(courseVO.getName()))
                return new ResultVO<>(Constant.REQUEST_FAIL, "已存在同名课程！");
        }

        Course course = new Course(courseVO);
        if(courseMapper.insert(course) > 0){
            return new ResultVO<CourseVO>(Constant.REQUEST_SUCCESS, "课程创建成功。", new CourseVO(course, false, true));
        }
        return new ResultVO<>(Constant.REQUEST_FAIL, "服务器错误");
    }


    @Override
    public Course getByPrimaryKey(Integer courseId) {
        return courseMapper.selectByPrimaryKey(courseId);
    }

    // todo 实现setCourseLike方法
    @Override
    public ResultVO<CourseVO> setCourseLike(Integer uid, Integer courseId) {
        /*
            1. 先判断ID为uid的用户是否给课程ID为courseId点过赞:
                1.1 若点过赞（count == 1）:
                    返回错误信息。（假设此接口的前置条件是没有点过赞）
                1.2 若没点过赞 （count == 0):
                    insert一条记录进course_likes表
                    返回成功信息

         */
        if (courseLikesMapper.count(courseId, uid) == 1){
            return new ResultVO<>(Constant.REQUEST_FAIL, "已点过赞！");
        }
        else{
            // todo 修改courseLikesMapper.xml的insert、deleteByPrimaryKey的实现（参照了别的xml文件的写法）
            if(courseLikesMapper.insert(courseId,uid) > 0){
                return new ResultVO<>(Constant.REQUEST_SUCCESS, "成功点赞");
            }
            return new ResultVO<>(Constant.REQUEST_FAIL, "服务器错误qvq");
        }
    }

    // todo 实现cancelCourseLike方法
    @Override
    public ResultVO<CourseVO> cancelCourseLike(Integer uid, Integer courseId) {
        /*
            1. 先判断ID为uid的用户是否给课程ID为courseId点过赞:
                1.1 若没点过赞（count == 0）:
                    返回错误信息。（假设此接口的前置条件是已经点过赞）
                1.2 若点过赞 （count == 1):
                    insert一条记录进course_likes表
                    返回成功信息
         */
        if (courseLikesMapper.count(courseId, uid) == 0){
            return new ResultVO<>(Constant.REQUEST_FAIL, "没有点赞过该课程");
        }
        else{
            if(courseLikesMapper.deleteByPrimaryKey(courseId,uid) > 0){
                return new ResultVO<>(Constant.REQUEST_SUCCESS, "成功取消点赞");
            }
            return new ResultVO<>(Constant.REQUEST_FAIL, "服务器错误");
        }
    }

    private PageInfo<CourseVO> getCourseVOPageInfo(Integer uid, PageInfo<Course> po) {
        PageInfo<CourseVO> result = PageInfoUtil.convert(po, CourseVO.class);
        if(uid != null && uid > 0){
            List<CourseVO> voList = result.getList();
            for(CourseVO vo: voList){
                CourseOrder order = orderService.queryMostRecentOrder(uid, vo.getId());
                if(order != null)
                    vo.setBought(order.getStatus().equals(Constant.ORDER_STATUS_SUCCESS));
                // 只有在uid==课程老师的id时，才将manageable权限改为true
                // 即学生的manageable权限都为false
                vo.setManageable(uid.equals(vo.getTeacherId()));
                // todo 新增一个接口调用，用来更新用户A对课程C的点赞状态
                // 在vo/course/CourseVO.java中新增方法setliked(boolean isliked)
                vo.setLiked(getliked(uid, vo.getId()));
            }
        }
        return result;
    }

    // todo 新增一个getliked方法
    private boolean getliked(Integer uid, Integer courseId){
        if (courseLikesMapper.count(courseId,uid) == 1)
            return true;
        else
            return false;
    }
}
